package com.zoe.onelink.circuitbreaker.sentinel;

import com.alibaba.cloud.circuitbreaker.sentinel.SentinelCircuitBreaker;
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.Tracer;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.zoe.onelink.common.circuitbreaker.FallbackException;

import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * <p>标题: </p>
 * <p>描述: </p>
 * <p>版权: Copyright (c) 2023</p>
 * <p>公司: 智业软件股份有限公司</p>
 *
 * @version: 1.0
 * @author: ruansheng
 * @date: 2023-01-17
 */
public class OnelinkSentinelCircuitBreaker extends SentinelCircuitBreaker {

    private final String resourceName;

    private final EntryType entryType;

    public OnelinkSentinelCircuitBreaker(String resourceName, EntryType entryType,
                                         List<DegradeRule> rules) {
        super(resourceName, entryType, rules);
        this.resourceName = resourceName;
        this.entryType = entryType;

    }

    public OnelinkSentinelCircuitBreaker(String resourceName, List<DegradeRule> rules) {
        this(resourceName, EntryType.OUT, rules);
    }

    public OnelinkSentinelCircuitBreaker(String resourceName) {
        this(resourceName, EntryType.OUT, Collections.emptyList());
    }

    @Override
    public <T> T run(Supplier<T> toRun, Function<Throwable, T> fallback) {
        Entry entry = null;
        try {
            entry = SphU.entry(resourceName, entryType);
            return toRun.get();
            // 触发断路器异常
        } catch (BlockException ex) {
            return fallback.apply(new FallbackException(ex));
            // 其他异常
        } catch (Exception ex) {
            Tracer.trace(ex);
            return fallback.apply(ex);
        } finally {
            if (entry != null) {
                entry.exit();
            }
        }
    }
}
